﻿using StableDiffusionTools.Enums;
using StableDiffusionTools.Utils;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;

namespace StableDiffusionTools.AUTOMATIC1111
{
    public static class WebUIAPI
    {
        const string LoopbackIP = "127.0.0.1";
        public static int WebUIPort { get; set; }
        
        public static async Task<RequestResult<string>> InterrogateRequest(InterrogateModel model, string imgData)
        {
            var requestJSON = new JsonObject
            {
                ["image"] = imgData,
                ["model"] = EnumUtil.GetName(model),
            };

            var result = await HttpClientUtil.PostJSON($"{FormatAPIUrl("interrogate")}", requestJSON.ToJsonString()).ConfigureAwait(false);
            string cap = "";
            if (result.Success && result.Data != null && result.Data.RootElement.TryGetProperty("caption", out JsonElement caption))
            {
                cap = caption.GetString();
            }

            result.Data?.Dispose();
            return new RequestResult<string>(cap, result.Error, result.Success && result.Data != null);
        }

        public static async Task<RequestResult<bool>> RefreshCheckpoints()
        {
            var result = await HttpClientUtil.PostJSON($"{FormatAPIUrl("refresh-checkpoints")}");
            result.Data?.Dispose();

            return new RequestResult<bool>(false, result.Error, result.Success);
        }

        public static async Task<RequestResult<bool>> UnloadCheckpoint()
        {
            var result = await HttpClientUtil.PostJSON($"{FormatAPIUrl("unload-checkpoints")}");
            result.Data?.Dispose();

            return new RequestResult<bool>(false, result.Error, result.Success);
        }

        public static async Task<RequestResult<List<Checkpoint>>> GetCheckpoints()
        {
            return await HttpClientUtil.GetJson<List<Checkpoint>>($"{FormatAPIUrl("sd-models")}");
        }

        public static async Task<RequestResult<List<ScriptInfo>>> GetScriptInfo()
        {
            return await HttpClientUtil.GetJson<List<ScriptInfo>>($"{FormatAPIUrl("script-info")}");
        }

        public static async Task<RequestResult<Options>> GetOptions()
        {
            return await HttpClientUtil.GetJson<Options>($"{FormatAPIUrl("options")}");
        }

        public static async Task<RequestResult<bool>> SetOptions(Options options)
        {
            var result = await HttpClientUtil.PostJSON($"{FormatAPIUrl("options")}", JsonSerializer.Serialize(options));
            result.Data?.Dispose();

            return new RequestResult<bool>(false, result.Error, result.Success);
        }

        private static string FormatAPIUrl(string apiName)
        {
            return $"http://{LoopbackIP}:{WebUIPort}/sdapi/v1/{apiName}";
        }
    }
}
